import { Vue } from './install';

const forEach = (obj, callback) => {
  Object.keys(obj).forEach(key => {
    callback && callback(key, obj[key]);
  });
};

class Module {
  constructor(rootModule) {
    this._raw = rootModule;
    this._children = {};
    this.state = rootModule.state;
  }
  getChild(key) {
    return this._children[key];
  }
  addChild(key, module) {
    this._children[key] = module;
  }
}

class ModuleCollection {
  constructor(options) {
    this.register([], options);
  }

  //   /**
  //    * 把用户传递的参数构建符合编码要求的树形结构核心，
  //    * 已经是父子关系了，想在上面添加一些属性，以后有父子关系都可以这么搞
  //    * 
  //    * @param {*} path 是构建与模块形成父子关系的栈结构
  //    * @param {*} rootModule 用户的参数
  //    */
  //   register(path, rootModule) {
  //     const module = {
  //       _raw: rootModule,
  //       _children: {},
  //       state: rootModule.state,
  //     };

  //     if (path.length === 0) {
  //       this.root = module;
  //     } else {
  //       // 形成父子关系的核心，先找到父亲
  //       const parent = path.slice(0, -1).reduce((memo, current) => {
  //         return memo._children[current];
  //       }, this.root);

  //       parent._children[path[path.length - 1]] = module;
  //     }

  //     // 用户传递了 modules
  //     if (rootModule.modules) {
  //       forEach(rootModule.modules, (moduleName, moduleValue) => {
  //         this.register(path.concat(moduleName), moduleValue);
  //       })
  //     }
  //   }

  /**
   * 把用户传递的参数构建符合编码要求的树形结构核心，
   * 已经是父子关系了，想在上面添加一些属性，以后有父子关系都可以这么搞
   * 
   * @param {*} path 是构建与模块形成父子关系的栈结构
   * @param {*} rootModule 用户的参数
   */
  register(path, rootModule) {
    const module = new Module(rootModule);

    if (path.length === 0) {
      this.root = module;
    } else {
      // 形成父子关系的核心，先找到父亲
      const parent = path.slice(0, -1).reduce((memo, current) => {
        return memo.getChild(current);
      }, this.root);

      parent.addChild(path[path.length - 1], module);
    }

    // 用户传递了 modules
    if (rootModule.modules) {
      forEach(rootModule.modules, (moduleName, moduleValue) => {
        this.register(path.concat(moduleName), moduleValue);
      })
    }
  }
}


class Store {
  constructor(options) {
    console.log(options);
    // 转换用户传递属性格式
    const modules = new ModuleCollection(options);
    console.dir(modules, { depth: true })
  }

  // commit 挂载到 $store 上供用户调用， $store.commit("xxx", payload)
  commit = (mutationKey, payload) => {
  }

  // dispatch 挂载到 $store 上供用户调用， $store.dispatch("xxx", payload)
  dispatch = (actionKey, payload) => {
  }

  get state() {
  }

}


// class Store {
//   constructor(options) {
//     console.log(options)
//     // 用户的 state
//     const state = options.state;

//     this.getters = {};
//     // 用户的 getters
//     const getters = options.getters;
//     // 把 getters 放在 state 上不友好，每取一次就执行一次，消耗性能，因此，把 getter 定义到 compunted 来处理，他有缓存作用
//     // forEach(getters, (getterKey, getterValue) => {
//     //   Object.defineProperty(this.getters, getterKey, {
//     //     get: () => {
//     //       return getterValue.call(this, this.state);
//     //     }
//     //   });
//     // });
//     const computed = {};
//     forEach(getters, (getterKey, getterValue) => {
//       // 把 getters 的相关属性作为计算属性处理，有缓存作用，防止多次取值时消耗性能。
//       computed[getterKey] = () => {
//         return getterValue.call(this, this.state);
//       };

//       Object.defineProperty(this.getters, getterKey, {
//         get: () => this.vm[getterKey],
//       });
//     });


//     this.vm = new Vue({
//       data: {
//         $$state: state  // vue 内部处理了 $不被代理所以 使用 $$
//       },
//       computed
//     });

//     this.mutations = {};
//     // 用户的 mutations
//     const mutations = options.mutations;
//     forEach(mutations, (mutationKey, mutationValue) => {
//       this.mutations[mutationKey] = (payload) => mutationValue(this.state, payload);
//     });

//     this.actions = {};
//     // 用户的 mutations
//     const actions = options.actions;
//     forEach(actions, (actionKey, actionValue) => {
//       this.actions[actionKey] = (payload) => actionValue(this, payload);
//     });

//   }

//   // commit 挂载到 $store 上供用户调用， $store.commit("xxx", payload)
//   commit = (mutationKey, payload) => {
//     this.mutations[mutationKey](payload);
//   }

//   // dispatch 挂载到 $store 上供用户调用， $store.dispatch("xxx", payload)
//   dispatch = (actionKey, payload) => {
//     this.actions[actionKey](payload);
//   }

//   get state() {
//     // 通过中间层获取用户的 state
//     return this.vm._data.$$state;
//   }

// }

export default Store;